<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>FFmpeg网页版音视频转换工具 - 新拟物风格</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/ffmpeg/0.11.6/ffmpeg.min.js"></script>
    <style>
      * {
        box-sizing: border-box;
        margin: 0;
        padding: 0;
        font-family: 'SF Pro Display', 'PingFang SC', 'Helvetica Neue', Arial,
          sans-serif;
      }

      :root {
        --primary-bg: #e6e7ee;
        --secondary-bg: #ffffff;
        --shadow-light: #ffffff;
        --shadow-dark: #d1d9e6;
        --accent-color: #667eea;
        --accent-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        --success-color: #4ecdc4;
        --danger-color: #ff6b6b;
        --warning-color: #feca57;
        --text-primary: #2d3748;
        --text-secondary: #718096;
        --glass-bg: rgba(255, 255, 255, 0.25);
        --glass-border: rgba(255, 255, 255, 0.18);
      }

      body {
        background: var(--primary-bg);
        color: var(--text-primary);
        min-height: 100vh;
        padding: 20px;
        display: flex;
        flex-direction: column;
        align-items: center;
        transition: all 0.3s ease;
        animation: pageLoad 0.8s ease;
      }

      @keyframes pageLoad {
        from {
          opacity: 0;
          transform: translateY(20px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      .container {
        width: 100%;
        max-width: 1200px;
        background: var(--primary-bg);
        border-radius: 30px;
        padding: 40px;
        box-shadow: 20px 20px 60px var(--shadow-dark),
          -20px -20px 60px var(--shadow-light);
        margin-top: 20px;
        transition: all 0.3s ease;
        animation: containerFloat 1s ease 0.2s both;
      }

      @keyframes containerFloat {
        from {
          opacity: 0;
          transform: translateY(30px) scale(0.95);
        }
        to {
          opacity: 1;
          transform: translateY(0) scale(1);
        }
      }

      .container:hover {
        box-shadow: 25px 25px 70px var(--shadow-dark),
          -25px -25px 70px var(--shadow-light);
      }

      header {
        text-align: center;
        margin-bottom: 40px;
        padding: 30px;
        background: var(--primary-bg);
        border-radius: 25px;
        box-shadow: 10px 10px 20px var(--shadow-dark),
          -10px -10px 20px var(--shadow-light);
        animation: headerSlide 0.8s ease 0.4s both;
      }

      @keyframes headerSlide {
        from {
          opacity: 0;
          transform: translateY(-30px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      h1 {
        font-size: 3.2rem;
        margin-bottom: 15px;
        background: var(--accent-gradient);
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
        background-clip: text;
        font-weight: 700;
        animation: titleGlow 3s ease-in-out infinite alternate;
      }

      @keyframes titleGlow {
        from {
          filter: brightness(1);
        }
        to {
          filter: brightness(1.2);
        }
      }

      .subtitle {
        font-size: 1.3rem;
        color: var(--text-secondary);
        margin-bottom: 30px;
        font-weight: 500;
      }

      .panels {
        display: flex;
        gap: 30px;
        margin-bottom: 40px;
        animation: panelsSlide 0.8s ease 0.6s both;
      }

      @keyframes panelsSlide {
        from {
          opacity: 0;
          transform: translateX(-20px);
        }
        to {
          opacity: 1;
          transform: translateX(0);
        }
      }

      .panel {
        flex: 1;
        background: var(--primary-bg);
        border-radius: 25px;
        padding: 30px;
        box-shadow: 12px 12px 24px var(--shadow-dark),
          -12px -12px 24px var(--shadow-light);
        transition: all 0.3s ease;
        position: relative;
        overflow: hidden;
      }

      .panel::before {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.1),
          transparent
        );
        transition: left 0.8s;
      }

      .panel:hover::before {
        left: 100%;
      }

      .panel:hover {
        transform: translateY(-5px);
        box-shadow: 16px 16px 32px var(--shadow-dark),
          -16px -16px 32px var(--shadow-light);
      }

      .panel-title {
        font-size: 1.6rem;
        margin-bottom: 25px;
        color: var(--accent-color);
        display: flex;
        align-items: center;
        font-weight: 600;
      }

      .panel-title::before {
        content: attr(data-icon);
        margin-right: 12px;
        font-size: 1.8rem;
        animation: iconBounce 2s ease-in-out infinite;
      }

      @keyframes iconBounce {
        0%,
        100% {
          transform: scale(1);
        }
        50% {
          transform: scale(1.1);
        }
      }

      .file-upload {
        border: 3px dashed var(--accent-color);
        border-radius: 25px;
        padding: 50px 40px;
        text-align: center;
        transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
        margin-bottom: 25px;
        cursor: pointer;
        background: var(--primary-bg);
        box-shadow: inset 8px 8px 16px var(--shadow-dark),
          inset -8px -8px 16px var(--shadow-light);
        position: relative;
        overflow: hidden;
      }

      .file-upload:hover {
        border-color: var(--success-color);
        transform: translateY(-5px) scale(1.02);
        box-shadow: inset 10px 10px 20px var(--shadow-dark),
          inset -10px -10px 20px var(--shadow-light),
          0 15px 40px rgba(102, 126, 234, 0.25);
      }

      .file-upload.dragover {
        border-color: var(--success-color);
        background: rgba(78, 205, 196, 0.05);
        transform: scale(1.05);
        box-shadow: inset 12px 12px 24px var(--shadow-dark),
          inset -12px -12px 24px var(--shadow-light),
          0 20px 50px rgba(78, 205, 196, 0.3);
        animation: dragPulse 1s ease-in-out infinite;
      }

      @keyframes dragPulse {
        0%,
        100% {
          border-color: var(--success-color);
        }
        50% {
          border-color: var(--accent-color);
        }
      }

      .file-upload-content {
        position: relative;
        z-index: 1;
      }

      .file-upload-icon {
        font-size: 3.5rem;
        margin-bottom: 20px;
        display: block;
        animation: iconFloat 3s ease-in-out infinite;
      }

      @keyframes iconFloat {
        0%,
        100% {
          transform: translateY(0);
        }
        50% {
          transform: translateY(-10px);
        }
      }

      .file-upload-text {
        font-size: 1.4rem;
        font-weight: 600;
        color: var(--text-primary);
        margin-bottom: 10px;
        background: var(--accent-gradient);
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
        background-clip: text;
      }

      .file-upload-subtext {
        font-size: 1.1rem;
        color: var(--text-secondary);
        margin-bottom: 20px;
        font-weight: 500;
      }

      .file-upload-formats {
        font-size: 0.9rem;
        color: var(--accent-color);
        font-weight: 500;
        padding: 8px 16px;
        background: rgba(102, 126, 234, 0.1);
        border-radius: 20px;
        display: inline-block;
        margin-bottom: 20px;
      }

      .file-upload input[type='file'] {
        position: absolute;
        width: 100%;
        height: 100%;
        top: 0;
        left: 0;
        opacity: 0;
        cursor: pointer;
        z-index: 2;
      }

      .video-preview {
        width: 100%;
        background: var(--primary-bg);
        border-radius: 20px;
        overflow: hidden;
        margin-top: 20px;
        box-shadow: inset 10px 10px 20px var(--shadow-dark),
          inset -10px -10px 20px var(--shadow-light);
      }

      video {
        width: 100%;
        max-height: 300px;
        display: block;
        border-radius: 15px;
      }

      .options-form {
        display: flex;
        gap: 20px;
        margin-bottom: 25px;
        flex-wrap: wrap;
        align-items: flex-end;
      }

      .form-group {
        flex: 1;
        min-width: 150px;
      }

      label {
        display: block;
        margin-bottom: 10px;
        color: var(--text-secondary);
        font-weight: 500;
        font-size: 0.95rem;
      }

      input,
      select {
        width: 100%;
        padding: 14px 18px;
        background: var(--primary-bg);
        border: none;
        border-radius: 15px;
        color: var(--text-primary);
        font-size: 1rem;
        font-weight: 500;
        box-shadow: inset 6px 6px 12px var(--shadow-dark),
          inset -6px -6px 12px var(--shadow-light);
        transition: all 0.3s ease;
      }

      input:focus,
      select:focus {
        outline: none;
        box-shadow: inset 8px 8px 16px var(--shadow-dark),
          inset -8px -8px 16px var(--shadow-light),
          0 0 0 3px rgba(102, 126, 234, 0.2);
      }

      button {
        background: var(--primary-bg);
        color: var(--text-primary);
        border: none;
        padding: 14px 28px;
        border-radius: 15px;
        cursor: pointer;
        font-weight: 600;
        transition: all 0.3s ease;
        font-size: 1rem;
        flex-shrink: 0;
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light);
        position: relative;
        overflow: hidden;
      }

      button::before {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.2),
          transparent
        );
        transition: left 0.5s;
      }

      button:hover::before {
        left: 100%;
      }

      button:hover {
        transform: translateY(-3px);
        box-shadow: 12px 12px 24px var(--shadow-dark),
          -12px -12px 24px var(--shadow-light);
      }

      button:active {
        transform: translateY(0);
        box-shadow: inset 6px 6px 12px var(--shadow-dark),
          inset -6px -6px 12px var(--shadow-light);
      }

      button:disabled {
        opacity: 0.6;
        cursor: not-allowed;
        transform: none;
        box-shadow: 4px 4px 8px var(--shadow-dark),
          -4px -4px 8px var(--shadow-light);
      }

      .btn-primary {
        background: var(--accent-gradient);
        color: white;
        padding: 16px 32px;
        font-size: 1.1rem;
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light),
          inset 0 1px 0 rgba(255, 255, 255, 0.2);
      }

      .btn-primary:hover {
        box-shadow: 12px 12px 24px var(--shadow-dark),
          -12px -12px 24px var(--shadow-light),
          inset 0 1px 0 rgba(255, 255, 255, 0.2),
          0 0 30px rgba(102, 126, 234, 0.3);
      }

      .btn-success {
        background: linear-gradient(
          135deg,
          var(--success-color) 0%,
          #44a08d 100%
        );
        color: white;
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light),
          inset 0 1px 0 rgba(255, 255, 255, 0.2);
      }

      .progress-container {
        margin: 30px 0;
        animation: progressSlide 0.8s ease 0.8s both;
      }

      @keyframes progressSlide {
        from {
          opacity: 0;
          transform: translateY(20px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      .progress-bar {
        height: 16px;
        background: var(--primary-bg);
        border-radius: 20px;
        overflow: hidden;
        margin-bottom: 15px;
        box-shadow: inset 6px 6px 12px var(--shadow-dark),
          inset -6px -6px 12px var(--shadow-light);
        position: relative;
      }

      .progress-fill {
        height: 100%;
        background: var(--accent-gradient);
        width: 0%;
        transition: width 0.3s ease;
        border-radius: 20px;
        box-shadow: 0 2px 10px rgba(102, 126, 234, 0.3);
        position: relative;
        overflow: hidden;
      }

      .progress-fill::after {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.3),
          transparent
        );
        animation: progressShine 2s infinite;
      }

      @keyframes progressShine {
        0% {
          left: -100%;
        }
        100% {
          left: 100%;
        }
      }

      .progress-text {
        text-align: center;
        font-size: 1rem;
        color: var(--text-secondary);
        font-weight: 500;
      }

      .actions {
        display: flex;
        justify-content: center;
        gap: 25px;
        margin-top: 30px;
        animation: actionsSlide 0.8s ease 1s both;
      }

      @keyframes actionsSlide {
        from {
          opacity: 0;
          transform: translateY(20px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      .result-panel {
        text-align: center;
        animation: resultPanelSlide 0.8s ease 1.2s both;
      }

      @keyframes resultPanelSlide {
        from {
          opacity: 0;
          transform: translateY(30px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      .status-message {
        min-height: 35px;
        margin: 20px 0;
        color: var(--accent-color);
        font-weight: 600;
        font-size: 1.1rem;
        transition: all 0.3s ease;
      }

      .status-message.processing {
        animation: statusPulse 1.5s ease-in-out infinite;
      }

      @keyframes statusPulse {
        0%,
        100% {
          opacity: 1;
        }
        50% {
          opacity: 0.6;
        }
      }

      .error-message {
        color: var(--danger-color);
        margin: 20px 0;
        min-height: 35px;
        font-weight: 600;
        font-size: 1.1rem;
        animation: errorShake 0.5s ease;
      }

      @keyframes errorShake {
        0%,
        100% {
          transform: translateX(0);
        }
        25% {
          transform: translateX(-5px);
        }
        75% {
          transform: translateX(5px);
        }
      }

      .download-section {
        display: flex;
        flex-direction: column;
        gap: 20px;
        margin-top: 30px;
        padding: 25px;
        background: var(--primary-bg);
        border-radius: 25px;
        box-shadow: 10px 10px 20px var(--shadow-dark),
          -10px -10px 20px var(--shadow-light);
        border: 2px solid var(--accent-color);
      }

      .download-items {
        display: flex;
        gap: 15px;
        flex-wrap: wrap;
        justify-content: center;
      }

      .download-item {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 15px 20px;
        background: var(--primary-bg);
        border-radius: 20px;
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light);
        transition: all 0.3s ease;
        border: 1px solid rgba(102, 126, 234, 0.1);
        flex: 1;
        min-width: 280px;
        max-width: 400px;
      }

      .download-item:hover {
        transform: translateY(-2px);
        box-shadow: 12px 12px 24px var(--shadow-dark),
          -12px -12px 24px var(--shadow-light);
        border-color: var(--accent-color);
      }

      .download-title {
        font-size: 1rem;
        font-weight: 600;
        color: var(--text-primary);
        display: flex;
        align-items: center;
        gap: 8px;
      }

      .download-size {
        font-size: 0.9rem;
        color: var(--text-secondary);
        font-weight: 500;
        padding: 6px 12px;
        background: rgba(102, 126, 234, 0.1);
        border-radius: 15px;
        border: 1px solid rgba(102, 126, 234, 0.2);
        margin: 0 10px;
      }

      .instructions {
        background: var(--primary-bg);
        border-radius: 25px;
        padding: 30px;
        margin-top: 40px;
        box-shadow: 10px 10px 20px var(--shadow-dark),
          -10px -10px 20px var(--shadow-light);
        animation: instructionsSlide 0.8s ease 1.4s both;
      }

      @keyframes instructionsSlide {
        from {
          opacity: 0;
          transform: translateY(30px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      .instructions h3 {
        color: var(--accent-color);
        margin-bottom: 20px;
        font-size: 1.4rem;
        font-weight: 600;
      }

      .instructions ol {
        padding-left: 25px;
        margin-bottom: 20px;
      }

      .instructions li {
        margin-bottom: 12px;
        line-height: 1.7;
        color: var(--text-secondary);
        font-weight: 500;
      }

      .instructions p {
        color: var(--text-secondary);
        font-style: italic;
        font-weight: 500;
        padding: 15px;
        background: rgba(102, 126, 234, 0.1);
        border-radius: 15px;
        border-left: 4px solid var(--accent-color);
      }

      footer {
        margin-top: 40px;
        text-align: center;
        color: var(--text-secondary);
        font-size: 0.95rem;
        padding: 25px;
        background: var(--primary-bg);
        border-radius: 20px;
        box-shadow: 6px 6px 12px var(--shadow-dark),
          -6px -6px 12px var(--shadow-light);
        animation: footerFade 0.8s ease 1.6s both;
      }

      @keyframes footerFade {
        from {
          opacity: 0;
        }
        to {
          opacity: 1;
        }
      }

      @media (max-width: 768px) {
        .panels {
          flex-direction: column;
        }

        .container {
          padding: 20px;
          margin: 10px;
        }

        h1 {
          font-size: 2.5rem;
        }

        .options-form {
          flex-direction: column;
        }
      }
    </style>
  </head>
  <body>
    <div class="container">
      <header>
        <h1>🎬 FFmpeg 网页版转换工具</h1>
        <p class="subtitle">强大的在线音视频格式转换器 - 新拟物设计风格</p>
      </header>

      <div class="panels">
        <div class="panel">
          <h2 class="panel-title" data-icon="📁">文件上传</h2>

          <div class="file-upload" id="fileUpload">
            <div class="file-upload-content">
              <div class="file-upload-icon">📁</div>
              <div class="file-upload-text">拖拽文件到此处</div>
              <div class="file-upload-subtext">或点击选择文件</div>
              <div class="file-upload-formats">
                支持格式: MP4, AVI, MKV, MOV, FLV, WebM, MP3, WAV, AAC等
              </div>
            </div>
            <input type="file" id="fileInput" accept="video/*,audio/*" />
          </div>

          <div class="video-preview" id="videoPreview" style="display: none">
            <video id="previewVideo" controls></video>
          </div>

          <div id="fileInfo" style="display: none">
            <div class="form-group">
              <label>文件名:</label>
              <input type="text" id="fileName" readonly />
            </div>
            <div class="form-group">
              <label>文件大小:</label>
              <input type="text" id="fileSize" readonly />
            </div>
            <div class="form-group">
              <label>原始格式:</label>
              <input type="text" id="originalFormat" readonly />
            </div>
          </div>
        </div>

        <div class="panel">
          <h2 class="panel-title" data-icon="⚙️">转换设置</h2>

          <div class="options-form">
            <div class="form-group">
              <label for="outputFormat">输出格式</label>
              <select id="outputFormat">
                <option value="mp4">MP4 - 通用视频格式</option>
                <option value="avi">AVI - 高质量视频</option>
                <option value="mkv">MKV - 多媒体容器</option>
                <option value="flv">FLV - Flash视频格式</option>
                <option value="m3u8">M3U8 - HLS流媒体</option>
                <option value="webm">WebM - 网页视频</option>
                <option value="mov">MOV - QuickTime</option>
                <option value="mp3">MP3 - 音频格式</option>
                <option value="wav">WAV - 无损音频</option>
                <option value="aac">AAC - 高质量音频</option>
                <option value="ogg">OGG - 开源音频</option>
              </select>
            </div>

            <div class="form-group">
              <label for="videoCodec">视频编码器</label>
              <select id="videoCodec">
                <option value="libx264">H.264 (推荐)</option>
                <option value="libx265">H.265/HEVC</option>
                <option value="libvpx-vp9">VP9</option>
                <option value="mpeg4">MPEG-4</option>
              </select>
            </div>

            <div class="form-group">
              <label for="audioCodec">音频编码器</label>
              <select id="audioCodec">
                <option value="aac">AAC (推荐)</option>
                <option value="mp3">MP3</option>
                <option value="opus">Opus</option>
                <option value="vorbis">Vorbis</option>
              </select>
            </div>
          </div>

          <div class="options-form">
            <div class="form-group">
              <label for="videoBitrate">视频比特率</label>
              <select id="videoBitrate">
                <option value="1000k">1 Mbps (低质量)</option>
                <option value="2500k" selected>2.5 Mbps (标准)</option>
                <option value="5000k">5 Mbps (高质量)</option>
                <option value="8000k">8 Mbps (超高质量)</option>
              </select>
            </div>

            <div class="form-group">
              <label for="audioBitrate">音频比特率</label>
              <select id="audioBitrate">
                <option value="128k">128 kbps</option>
                <option value="192k" selected>192 kbps</option>
                <option value="320k">320 kbps (高质量)</option>
              </select>
            </div>

            <div class="form-group">
              <label for="resolution">分辨率</label>
              <select id="resolution">
                <option value="original">原始分辨率</option>
                <option value="1920x1080">1080p (Full HD)</option>
                <option value="1280x720">720p (HD)</option>
                <option value="854x480">480p (SD)</option>
              </select>
            </div>
          </div>

          <button id="convertBtn" class="btn-primary" disabled>
            🚀 开始转换
          </button>
        </div>
      </div>

      <div
        class="progress-container"
        id="progressContainer"
        style="display: none"
      >
        <div class="progress-bar">
          <div class="progress-fill" id="progressFill"></div>
        </div>
        <div class="progress-text" id="progressText">准备中...</div>
      </div>

      <div class="status-message" id="statusMessage"></div>
      <div class="error-message" id="errorMessage"></div>

      <div class="result-panel" id="resultPanel" style="display: none">
        <div class="download-section">
          <h3>📥 转换完成</h3>
          <div class="download-items" id="downloadItems">
            <!-- 下载链接将在这里生成 -->
          </div>
        </div>
      </div>

      <div class="instructions">
        <h3>📖 使用说明</h3>
        <ol>
          <li><strong>上传文件：</strong>拖拽文件到上传区域或点击选择文件</li>
          <li>
            <strong>选择格式：</strong
            >从下拉菜单中选择目标格式（支持FLV、M3U8、MKV、AVI等）
          </li>
          <li><strong>调整参数：</strong>根据需要调整编码器、比特率等参数</li>
          <li><strong>开始转换：</strong>点击"开始转换"按钮，等待处理完成</li>
          <li><strong>下载文件：</strong>转换完成后下载处理后的文件</li>
        </ol>
        <p>
          <strong>提示：</strong
          >FLV格式适合网页播放，M3U8适合HLS流媒体，MKV支持多种编码，AVI兼容性好。
        </p>
      </div>

      <footer>
        <p>🎨 基于 FFmpeg 的网页版音视频转换工具 | 新拟物设计风格</p>
      </footer>
    </div>

    <script>
      let ffmpeg = null
      let selectedFile = null

      // 初始化FFmpeg
      async function initFFmpeg() {
        if (!ffmpeg) {
          ffmpeg = FFmpeg.createFFmpeg({
            log: true,
            progress: ({ ratio }) => {
              const percent = Math.round(ratio * 100)
              updateProgress(percent)
            },
          })
          await ffmpeg.load()
        }
      }

      // 文件上传处理
      const fileUpload = document.getElementById('fileUpload')
      const fileInput = document.getElementById('fileInput')
      const previewVideo = document.getElementById('previewVideo')
      const videoPreview = document.getElementById('videoPreview')
      const fileInfo = document.getElementById('fileInfo')
      const convertBtn = document.getElementById('convertBtn')

      // 拖拽上传
      ;['dragenter', 'dragover', 'dragleave', 'drop'].forEach((eventName) => {
        fileUpload.addEventListener(eventName, preventDefaults, false)
      })

      function preventDefaults(e) {
        e.preventDefault()
        e.stopPropagation()
      }

      ;['dragenter', 'dragover'].forEach((eventName) => {
        fileUpload.addEventListener(eventName, () => {
          fileUpload.classList.add('dragover')
        })
      })

      ;['dragleave', 'drop'].forEach((eventName) => {
        fileUpload.addEventListener(eventName, () => {
          fileUpload.classList.remove('dragover')
        })
      })

      fileUpload.addEventListener('drop', (e) => {
        const files = e.dataTransfer.files
        if (files.length > 0) {
          handleFileSelect(files[0])
        }
      })

      fileInput.addEventListener('change', (e) => {
        if (e.target.files.length > 0) {
          handleFileSelect(e.target.files[0])
        }
      })

      function handleFileSelect(file) {
        selectedFile = file

        // 显示文件信息
        document.getElementById('fileName').value = file.name
        document.getElementById('fileSize').value = formatFileSize(file.size)
        document.getElementById('originalFormat').value = file.name
          .split('.')
          .pop()
          .toUpperCase()
        fileInfo.style.display = 'block'

        // 显示预览
        const url = URL.createObjectURL(file)
        if (file.type.startsWith('video/')) {
          previewVideo.src = url
          videoPreview.style.display = 'block'
        }

        convertBtn.disabled = false
      }

      function formatFileSize(bytes) {
        if (bytes === 0) return '0 Bytes'
        const k = 1024
        const sizes = ['Bytes', 'KB', 'MB', 'GB']
        const i = Math.floor(Math.log(bytes) / Math.log(k))
        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
      }

      // 转换处理
      convertBtn.addEventListener('click', async () => {
        if (!selectedFile) return

        try {
          await initFFmpeg()

          const outputFormat = document.getElementById('outputFormat').value
          const videoCodec = document.getElementById('videoCodec').value
          const audioCodec = document.getElementById('audioCodec').value
          const videoBitrate = document.getElementById('videoBitrate').value
          const audioBitrate = document.getElementById('audioBitrate').value
          const resolution = document.getElementById('resolution').value

          // 显示进度
          document.getElementById('progressContainer').style.display = 'block'
          document.getElementById('statusMessage').textContent =
            '正在处理文件...'
          document.getElementById('statusMessage').className =
            'status-message processing'

          // 构建输出文件名
          const outputFileName =
            selectedFile.name.replace(/\.[^/.]+$/, '') + '.' + outputFormat

          // 构建FFmpeg命令
          let command = ['-i', selectedFile.name]

          // 根据输出格式调整参数
          if (outputFormat === 'm3u8') {
            // HLS流媒体格式
            command.push('-hls_time', '10')
            command.push('-hls_playlist_type', 'vod')
            command.push('-f', 'hls')
          } else if (outputFormat === 'flv') {
            // FLV格式
            command.push('-c:v', 'libx264')
            command.push('-c:a', 'aac')
            command.push('-f', 'flv')
          } else {
            // 通用格式
            if (!selectedFile.type.startsWith('audio/')) {
              command.push('-c:v', videoCodec)
              command.push('-b:v', videoBitrate)
            }
            command.push('-c:a', audioCodec)
            command.push('-b:a', audioBitrate)

            if (resolution !== 'original') {
              command.push('-s', resolution)
            }
          }

          command.push(outputFileName)

          // 写入文件
          ffmpeg.FS(
            'writeFile',
            selectedFile.name,
            await fetchFile(selectedFile)
          )

          // 执行转换
          await ffmpeg.run(...command)

          // 读取输出文件
          let data
          let downloadUrl

          if (outputFormat === 'm3u8') {
            // HLS格式需要处理多个文件
            const m3u8Data = ffmpeg.FS('readFile', outputFileName)
            const blob = new Blob([m3u8Data.buffer], {
              type: 'application/x-mpegURL',
            })
            downloadUrl = URL.createObjectURL(blob)

            data = [
              {
                name: outputFileName,
                url: downloadUrl,
                size: m3u8Data.length,
              },
            ]
          } else {
            const outputData = ffmpeg.FS('readFile', outputFileName)
            const mimeType = getMimeType(outputFormat)
            const blob = new Blob([outputData.buffer], { type: mimeType })
            downloadUrl = URL.createObjectURL(blob)

            data = [
              {
                name: outputFileName,
                url: downloadUrl,
                size: outputData.length,
              },
            ]
          }

          // 显示结果
          displayResults(data)

          document.getElementById('statusMessage').textContent = '转换完成！'
          document.getElementById('statusMessage').className = 'status-message'
        } catch (error) {
          console.error('转换错误:', error)
          document.getElementById('errorMessage').textContent =
            '转换失败: ' + error.message
          document.getElementById('progressContainer').style.display = 'none'
        }
      })

      function getMimeType(format) {
        const mimeTypes = {
          mp4: 'video/mp4',
          avi: 'video/x-msvideo',
          mkv: 'video/x-matroska',
          flv: 'video/x-flv',
          m3u8: 'application/x-mpegURL',
          webm: 'video/webm',
          mov: 'video/quicktime',
          mp3: 'audio/mpeg',
          wav: 'audio/wav',
          aac: 'audio/aac',
          ogg: 'audio/ogg',
        }
        return mimeTypes[format] || 'application/octet-stream'
      }

      function updateProgress(percent) {
        document.getElementById('progressFill').style.width = percent + '%'
        document.getElementById(
          'progressText'
        ).textContent = `处理中... ${percent}%`
      }

      function displayResults(files) {
        const downloadItems = document.getElementById('downloadItems')
        downloadItems.innerHTML = ''

        files.forEach((file) => {
          const item = document.createElement('div')
          item.className = 'download-item'
          item.innerHTML = `
                    <div class="download-title">📄 ${file.name}</div>
                    <div class="download-size">${formatFileSize(
                      file.size
                    )}</div>
                    <button class="btn-success" onclick="downloadFile('${
                      file.url
                    }', '${file.name}')">
                        ⬇️ 下载
                    </button>
                `
          downloadItems.appendChild(item)
        })

        document.getElementById('resultPanel').style.display = 'block'
      }

      function downloadFile(url, filename) {
        const a = document.createElement('a')
        a.href = url
        a.download = filename
        document.body.appendChild(a)
        a.click()
        document.body.removeChild(a)
      }

      async function fetchFile(file) {
        const response = await fetch(URL.createObjectURL(file))
        return new Uint8Array(await response.arrayBuffer())
      }
    </script>
  </body>
</html>
